Timo Sirainen [Wed, 3 Jun 2026 12:10:46 +0000 (12:10 +0000)]
[PATCH 3/7] lib-sieve: Rename on-disk header rusage fields to unused_*
The .svbin header's resource_usage fields no longer carry data: they
are zeroed on save and discarded on load. Cumulative CPU tracking
lives in the per-user sieve-rusage file, and the in-memory carry-over
lives in sbin->persisted_rusage.
Flatten the nested resource_usage struct and rename the fields to
unused_update_time and unused_cpu_time_msecs so it is obvious the
fields are kept only for on-disk format compatibility. The memory
layout of struct sieve_binary_header is unchanged.
Gbp-Pq: Name 0003-lib-sieve-Rename-on-disk-header-rusage-fields-to-unu.patch
Timo Sirainen [Tue, 5 May 2026 16:19:20 +0000 (16:19 +0000)]
[PATCH 2/7] lib-sieve: Drop binary-header resource usage tracking
With the per-user sieve-rusage file now authoritative for personal
storages, the .svbin header no longer needs to carry CPU usage. Admin
storages (sieve_before/after, default location) cannot be re-uploaded
by the user, so cross-run tracking is unnecessary there; the runtime
sieve_max_cpu_time check still enforces the per-execution limit.
Move the in-memory cumulative carry-over from sbin->header.resource_usage
to a dedicated sbin->persisted_rusage substruct. The on-disk header
struct now solely represents the wire format and is zeroed on every
save; the in-memory carry-over no longer overloads it. Drop the now-dead
"resource usage" section from sieve_binary_dumper_run() (the on-disk
fields are always zero, so the section never produced output).
Gbp-Pq: Name 0002-lib-sieve-Drop-binary-header-resource-usage-tracking.patch
Timo Sirainen [Tue, 5 May 2026 16:18:34 +0000 (16:18 +0000)]
[PATCH 1/7] lib-sieve: Add per-user sieve-rusage file for cumulative CPU tracking
Cumulative resource usage was previously stored in each compiled Sieve
binary's (.svbin) header. Because the binary file is keyed by script
name, a user could reset their CPU budget by uploading the same script
under a different name (PUTSCRIPT newname + SETACTIVE newname),
RENAMESCRIPT, or DELETESCRIPT followed by PUTSCRIPT under another
name. Each such operation produced a fresh .svbin with zero counter,
allowing the sieve_max_cpu_time limit to be bypassed indefinitely.
Track cumulative CPU per user instead, in <INBOX-namespace-root>/sieve-rusage.
The file persists across all script renames, deletions, and re-uploads,
since it is not tied to any particular script name. Tracking is enabled
only for personal storages where the user's INBOX namespace has a
filesystem path; admin/default storages are unaffected here.
The on-disk format is a single ASCII line:
V1 <flags> <cpu-secs> <update-time>
CPU time is rounded up to whole seconds when persisted; sub-second
precision is preserved only for the in-memory accumulation within a
single execution. The file is updated by writing a new copy via
file_dotlock_open_mode() and replacing the original via
file_dotlock_replace(). Concurrent writers are serialized through the
dotlock; readers do not need a lock because the rename is atomic.
The .svbin header still carries its original resource_usage struct as
the active fallback when no per-user file is available; a follow-up
commit drops that path.
Gbp-Pq: Name 0001-lib-sieve-Add-per-user-sieve-rusage-file-for-cumulat.patch
Stephan Bosch [Wed, 4 Mar 2026 20:53:36 +0000 (21:53 +0100)]
[PATCH] lib-sieve: sieve-storage - Fix panic caused by flawed detection of personal storage type
Recent commit d82c2e624e4a9c364a6fa58fad0938ae5578660c added the is_personal
flag, but it is assigned too late. Fix this issue by assigning this flag in the
earliest allocation function.
This issue commonly surfaces when people forget to set an appropriate type for a
script storage definition, in which case the "personal" type is the default.
Stephan Bosch [Tue, 25 Nov 2025 04:07:16 +0000 (05:07 +0100)]
[PATCH] lib-sieve: sieve-storage - Add is_personal bit
Simpler than evaluating the type and personal storage is created only through
sieve_storage_create_personal(). This mimics the bit for default storage.
Gbp-Pq: Name 0001-lib-sieve-sieve-storage-Add-is_personal-bit.patch
Timo Sirainen [Tue, 23 Jun 2026 15:26:51 +0000 (15:26 +0000)]
[PATCH 2/2] lib-storage: Simplify mailbox_mkdir() using mailbox_list_mkdir_root(NULL)
mailbox_mkdir() looked up the root path via mailbox_list_get_root_forced()
only to pass it straight to mailbox_list_mkdir_root(). Let mkdir_root()
resolve the root itself by passing path=NULL, dropping the local variable.
Gbp-Pq: Name 0002-lib-storage-Simplify-mailbox_mkdir-using-mailbox_lis.patch
Timo Sirainen [Tue, 23 Jun 2026 14:59:45 +0000 (14:59 +0000)]
[PATCH 1/2] lib-storage: Allow NULL path in mailbox_list_mkdir_root()
When path is NULL, look up the root directory path of the given type via
mailbox_list_get_root_path() and create that. If there is no path of the
requested type, nothing is done. This avoids open-coding the common
get_root_path() + mkdir_root() pair at call sites.
Gbp-Pq: Name 0001-lib-storage-Allow-NULL-path-in-mailbox_list_mkdir_ro.patch
Timo Sirainen [Mon, 6 Jul 2026 07:17:42 +0000 (07:17 +0000)]
[PATCH 2/3] doveadm: compress-connect - Don't hang when server rejects COMPRESS
After sending a COMPRESS command the client stopped reading stdin and
waited for the server's reply, but it only resumed on an "OK Begin
compression" reply. If the server rejected COMPRESS (e.g. a NO reply for
an unsupported mechanism), compress_waiting was never cleared: the client
waited forever for an OK that never came while the server waited for the
next command, deadlocking the session.
Remember the COMPRESS command tag and treat any tagged reply to it that
isn't the compression-start reply as a rejection, resuming the pipelined
input.
Gbp-Pq: Name 0002-doveadm-compress-connect-Don-t-hang-when-server-reje.patch
Timo Sirainen [Sat, 4 Jul 2026 21:57:15 +0000 (21:57 +0000)]
[PATCH 1/3] imap: Restrict COMPRESS to DEFLATE only
cmd_compress() and the imap-login proxy side channel looked up any
registered compression handler by name, so a client could request e.g.
COMPRESS ZSTD even though only COMPRESS=DEFLATE is advertised (RFC 4978).
Non-DEFLATE algorithms can require far more memory to decompress (a zstd
decoder alone can hold a 16+ MB window per connection versus ~40 KB for
inflate). This matters now that imap-login handles COMPRESS for proxied
connections: an attacker opening many connections could drive the shared
login process into its vsz_limit and crash it, affecting all clients on
that process.
Only accept DEFLATE on both the backend and the login proxy path.
Gbp-Pq: Name 0001-imap-Restrict-COMPRESS-to-DEFLATE-only.patch
Timo Sirainen [Wed, 22 Apr 2026 12:44:24 +0000 (15:44 +0300)]
[PATCH 2/3] imap-acl: Fail if ACL identifier is invalid
Reject invalid identifiers early in imap_acl_identifier_parse() using
acl_id_is_valid(). This prevents CR/LF injection and rejects identifiers
that are too long, contain control characters or are not valid UTF-8.
Timo Sirainen [Sun, 19 Apr 2026 23:10:29 +0000 (23:10 +0000)]
[PATCH] lib-sieve: Enforce CPU time limit within :contains and :matches matcher loops
The naive O(N*M) substring search in mcht-contains.c and the naive find loop
in mcht-matches.c can run for hours on a large value (e.g. a message body),
completely bypassing sieve_max_cpu_time because that limit was only checked
between bytecode operations.
Expose the active CPU limit via sieve_runtime_cpu_limit_exceeded() and poll
it every 4096 inner iterations. When the limit is hit the match returns
SIEVE_EXEC_RESOURCE_LIMIT, matching the existing behavior at the bytecode
boundary. This is a minimal safety net ahead of switching the matchers to
algorithms that do not require it.
Aki Tuomi [Fri, 25 Jul 2025 05:16:52 +0000 (08:16 +0300)]
[PATCH] auth: Use AUTH_CACHE_KEY_USER instead of per-database constants
Fixes cache key issue where users would end up overwriting
each other in cache due to cache key being essentially static
string because we no longer support %u.
Dovecot 2.4 introduced a regression that broke GSSAPI authentication for
some clients. This patch contains a fix provided by the upstream maintainers.
Last-Update: 2025-05-02
Gbp-Pq: Name bug1104549-gssapi-regression.patch
* Import upstream fixes for multiple security issues. (Closes: #1146018)
- CVE-2026-27852: DoS by sending mail with bad header
- CVE-2026-33263: submission-login: Panic when
mail_max_userip_connections is reached: Panic: epoll_ctl(del, 8)
failed: Bad file descriptor
- CVE-2026-33604: SMTP Smuggling via Missing Dot-Stuffing After Bare
Carriage Return
- CVE-2026-33605: managesieve-login: Pre-auth crash
- CVE-2026-33607: Dovecot IMAP LIST match_sub() Exponential
Backtracking — CPU Denial of Service
- CVE-2026-40013: pigeonhole: Stack Buffer Underflow in Pigeonhole
ManageSieve CHECKSCRIPT/PUTSCRIPT
- CVE-2026-40014: IMAP THREAD REFERENCES O(N²) CPU DoS via Crafted
References Header (index-thread-links.c)
- CVE-2026-40015: imap-hibernate can be crashed
- CVE-2026-40017: IMAP THREAD O(M³) CPU DoS via CRC32 Hash Collision
in strmap (mail-index-strmap.c / hash2.c)
- CVE-2026-40018: MySQL multi-byte escaping wrong
- CVE-2026-40204: acl: lda_mailbox_autocreate can bypass acl
restrictions
- CVE-2026-42007: Sieve editheader RCE
- CVE-2026-42391: imap: Pre-login memory/CPU growth with ID command
- CVE-2026-42394: sieve: symlink traversal flaw could result in
arbitrary file disclosure
- CVE-2026-52681: Sieve resource usage tracking lost when active
script changes
- CVE-2026-52687: IMAP: COMPRESS ZSTD can cause excessive memory usage
- CVE-2026-73209: imap-login crash: Self-recursion on zero-output
decompress chunks
- CVE-2026-33606: dsync: Mail content can cause dsync protocol
injection
- CVE-2026-40203: IMAP Compression Can Reveal Whether a Small Synced
Email Body Matches Sender-Chosen Text
- CVE-2026-42008: XCLIENT FORWARD= bare token not namespaced, allows
nopassword injection via trusted proxy
- CVE-2026-42392: imap-urlauth leaks memory into user-visible error
messages
- CVE-2026-42393: doveadm_password or api key length can still be
leaked with timing comparisons
- CVE-2026-42395: Single NUL-Byte XCLIENT FORWARD Payload Crashes
- CVE-2026-40205: OAuth2 passdb scope enforcement bypass via OR
semantics in remote validation path
- CVE-2026-73208: auth: db-oauth2: aud claim used as fallback for
missing scope claim
* lib-mail: istream-header-filter - Fix potential assert-crash
(Closes: #1144639)
* CI: Disable test-build-twice job, which is known to fail on trixie